/***************************************************************************
 *   Copyright (C) 2009 by umbacos@gmail.com                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "udm-common.h"
#include "udm-version.h"

#define FSIZE 500

char* dcgi;
char* droo;
char* dbin;
char* dwww;
char* dufb;
char* ddnl;
char* dtrk;
char* fcnf;
char* filter;
char* pidfile;
char* wget;
char* ctor;
char* mtomb_start;
char* mtomb_stop;
char* pCtor;
char* pWget;
char* argv0;

void * xmalloc ( size_t size );
void get_directories ( char * file );
int filter_select ( struct dirent *entry );
int fork2();
char * pipe_cmd ( const char * cmd );
void strip_last ( char * str, char ch );
#ifdef DEBUG
char * ltos(long long l);
#endif

/* Error and Msg */
void send_message ( char * msg, char * inf ) {

#ifdef DEBUG
	mylog ( msg, inf );
#endif
	printf ( "%s%s\n", msg, inf );
	exit ( 0 );
}

void setup_child () {

	int r;
	FILE* f;
	umask ( 0 );
	setsid();
	r = chdir ( dtrk );
	f = freopen ( "/dev/null", "r", stdin );
	f = freopen ( "/dev/null", "w", stdout );
	f = freopen ( "/dev/null", "w", stderr );

}

void check_version () {
	char cmd[1000];
	struct stat buf;
	int r;
	time_t tt;
	char curr[30];
	FILE * fp;

	r = chdir ( dwww );

#ifdef DEBUG
	mylog ( SERVER_SOFTWARE, ": *************************" );
	mylog ( SERVER_SOFTWARE, ": about to check_version...", "" );
#endif
	if (stat ( "version.html", &buf ) == 0) {
		tt=time(0);
#ifdef DEBUG
			mylog ( "current time: ", ctime(&tt));
			mylog ( "version time: ", ctime(&buf.st_mtime));
			mylog ( "current time: ", ltos(tt));
			mylog ( "version time: ", ltos(buf.st_mtime));
			mylog ( "  difference: ", ltos(tt - buf.st_mtime));
#endif
		if ( tt - buf.st_mtime > 86400 ) { /* once a day */
#ifdef DEBUG
			mylog ( "installed:", SERVER_VERSION );
#endif
			/* retrieve online version */
			unlink ( "version.html" );
			sprintf(cmd, "%s %s/version.html", wget, SERVER_URL);
			pipe_cmd ( cmd );
			/* done retrieve */

#ifdef DEBUG
			mylog ( "onlinever:", pipe_cmd ( "/bin/cat version.html" ) );
			mylog ( "reading  :", pipe_cmd ( "/bin/ls -l version.html" ) );
			mylog ( "wget was :", cmd );
			mylog ( "*************************", "" );
#endif
			sprintf(cmd, "%s/version.html", dwww);
			if ((fp = fopen ( cmd, "r" )) != NULL) {
				fgets ( curr, 30, fp );
				fclose ( fp );

				strip_last (curr, '\n');
				if ( strcmp ( curr, SERVER_VERSION ) != 0 ){
#ifdef DEBUG
					mylog ( "NEEDS-UPDATE!!!", "" );
					mylog ( curr, SERVER_VERSION );
#endif
					sprintf(cmd, "%s/_wversion.nfo", dtrk);
					fp = fopen ( cmd, "w" );
					fprintf ( fp, "Your version of %s is <b>%s</b> while the latest stable version is reported to be <b>%s</b>\n", SERVER_SOFTWARE, SERVER_VERSION, curr );
					fprintf ( fp, "Check on <a href=\"%s\">%s</a> to see if you need to upgrade to a newer version\n", SERVER_URL, SERVER_URL );
					fclose ( fp );
				}
			}
			/* touch version.html */
			fp = fopen ( "version.html", "w" );
			fclose ( fp );
			/* done touch */
		}
	}
#ifdef DEBUG
			mylog ( "done check_version", "" );
#endif
}

void batch_run () {

	struct stat buf;

	struct dirent **namelist;
	char * firstline = xmalloc ( FSIZE );
	char * lastline = xmalloc ( FSIZE );
	char * tailline;
	char * token;
	int n;
	char * q;
	FILE * fp;

	/*************************
	 * TRIM SIZE OF TRACKERS *
	 *************************/
#ifdef DEBUG
	mylog ( "start trim operations in ", dtrk );
#endif
	mkdir ( dtrk, 644 );
	n = chdir ( dtrk );

	filter = "";
	n = scandir ( dtrk, &namelist, ( void * ) filter_select, NULL );

	if ( n < 0 ) {
		syslog ( LOG_PERROR, "Scandir error for trk directory: %s", dtrk );
#ifdef DEBUG
		mylog ( "Scandir error for trk directory: ", dtrk );
#endif
	} else {
		while ( n-- ) {
			stat ( namelist[n]->d_name, &buf );

			if ( buf.st_size > FSIZE ) {
				firstline[0] = '\0';
				lastline[0] = '\0';
#ifdef DEBUG
				mylog ( "Trimming ", namelist[n]->d_name );
#endif
				/* HEAD */
				if ( ( fp = fopen ( namelist[n]->d_name, "r" ) ) == NULL ) {
					syslog ( LOG_PERROR, "fopen error in trk while reading %s\n", namelist[n]->d_name );
#ifdef DEBUG
					mylog ( "fopen error in trk while reading ", namelist[n]->d_name );
#endif
					} else {
					q = fgets ( firstline, FSIZE - 1, fp );
					}

				/* TAIL (dirty hack) */
				fseek ( fp, -FSIZE, SEEK_END );

				while ( fgets ( lastline, FSIZE, fp ) )
					if ( strlen ( lastline ) > 2 ) /* keep only lines longer than just CR or LF or CRLF*/
						tailline = strdup ( lastline ) ;

				if ( fclose ( fp ) == -1 ) {
					syslog ( LOG_PERROR, "fclose error in trk while reading %s\n", namelist[n]->d_name );
#ifdef DEBUG
					mylog ( "fclose error in trk while reading ", namelist[n]->d_name );
#endif
					}

				token = strtok ( tailline, "\r" );

				while ( token ) {
					if ( strlen ( token ) > 2 )
						strcpy ( lastline, token );

					token = strtok ( NULL, "\r" );
					}

				/* WRITE back to file */
				if ( ( fp = fopen ( namelist[n]->d_name, "w" ) ) == NULL ) {
					syslog ( LOG_PERROR, "fopen error in trk while writing %s\n", namelist[n]->d_name );
#ifdef DEBUG
					mylog ( "fopen error in trk while writing ", namelist[n]->d_name );
#endif
					} else {
						fputs ( firstline, fp );
						fputs ( lastline, fp );

						if ( fclose ( fp ) == -1 ) {
							syslog ( LOG_PERROR, "fclose error in trk while writing %s\n", namelist[n]->d_name );
#ifdef DEBUG
							mylog ( "fclose error in trk while writing ", namelist[n]->d_name );
#endif
						}
					}
				}

			free ( namelist[n] );
			}

		free ( namelist );
		}

	free ( firstline );

	free ( lastline );

	}

int main ( int argc, char** argv ) {

	setlocale(LC_ALL,"");

	openlog ( SERVER_SOFTWARE, LOG_PID, LOG_LOCAL5 );
	syslog ( LOG_INFO, "starting" );

	if ( fork2() == 1 ) {
		printf ( "\n*********************************\n");
		printf ( "%s %s\n", SERVER_SOFTWARE, SERVER_VERSION );
		printf ( "%s\n", SERVER_URL );
		printf ( "%s\n", EMAIL );
		printf ( "*********************************\n");
		printf ( "%s forking to background: bye...\n", SERVER_SOFTWARE );
		exit ( 0 );
		}

	setup_child ();
	get_directories ( strdup ( argv[0] ) );

	while ( 1 ) { /* main loop */

		if ( fork2() == 0 ) {
			setup_child ();
			check_version ();
			batch_run ();
			exit ( 0 );
			}

		sleep ( 60 );
#ifdef DEBUG
		/* keep logfile small */
		char cmd[1000];
		sprintf (cmd, "echo > %s", LOGFILE );
		pipe_cmd ( cmd );
		sleep( 1 );
#endif
		}

	syslog ( LOG_NOTICE, "strangely terminated here..." );

	closelog();
}
